"""
文本处理工具模块

提供文本清理、编码处理、时间格式化等功能。
"""

import re
import html
from typing import Optional, List, Dict, Any
from datetime import datetime
import unicodedata


class TextProcessor:
    """文本处理器"""

    # 常见的中文时间格式
    TIME_PATTERNS = [
        (r'(\d{4})年(\d{1,2})月(\d{1,2})日', r'\1-\2-\3'),
        (r'(\d{4})-(\d{1,2})-(\d{1,2})', r'\1-\2-\3'),
        (r'(\d{4})/(\d{1,2})/(\d{1,2})', r'\1-\2-\3'),
        (r'(\d{4})\.(\d{1,2})\.(\d{1,2})', r'\1-\2-\3'),
    ]

    # 需要移除的HTML标签
    HTML_TAGS_TO_REMOVE = [
        'script', 'style', 'head', 'title', 'meta', 'link',
        'iframe', 'object', 'embed', 'applet'
    ]

    def __init__(self):
        self.logger = None  # 将在使用时设置

    def set_logger(self, logger):
        """设置日志器"""
        self.logger = logger

    def clean_text(self, text: str, remove_html: bool = True,
                  normalize_whitespace: bool = True) -> str:
        """
        清理文本内容

        Args:
            text: 原始文本
            remove_html: 是否移除HTML标签
            normalize_whitespace: 是否标准化空白字符

        Returns:
            清理后的文本
        """
        if not text:
            return ""

        # 解码HTML实体
        text = html.unescape(text)

        # 移除HTML标签
        if remove_html:
            text = self._remove_html_tags(text)

        # 标准化空白字符
        if normalize_whitespace:
            text = self._normalize_whitespace(text)

        # 移除控制字符
        text = self._remove_control_chars(text)

        # 标准化Unicode字符
        text = self._normalize_unicode(text)

        return text.strip()

    def _remove_html_tags(self, text: str) -> str:
        """移除HTML标签"""
        # 移除脚本和样式标签及其内容
        for tag in self.HTML_TAGS_TO_REMOVE:
            pattern = rf'<{tag}[^>]*>.*?</{tag}>'
            text = re.sub(pattern, '', text, flags=re.IGNORECASE | re.DOTALL)

        # 移除其他HTML标签，保留内容
        text = re.sub(r'<[^>]+>', '', text)

        return text

    def _normalize_whitespace(self, text: str) -> str:
        """标准化空白字符"""
        # 将各种空白字符替换为单个空格
        text = re.sub(r'\s+', ' ', text)
        return text

    def _remove_control_chars(self, text: str) -> str:
        """移除控制字符"""
        # 移除不可打印的控制字符，保留换行符和制表符
        text = ''.join(char for char in text if char.isprintable() or char in '\n\t')
        return text

    def _normalize_unicode(self, text: str) -> str:
        """标准化Unicode字符"""
        # 使用NFKC标准化Unicode字符
        text = unicodedata.normalize('NFKC', text)
        return text

    def standardize_time(self, time_str: str, target_format: str = "%Y-%m-%d") -> str:
        """
        标准化时间格式

        Args:
            time_str: 原始时间字符串
            target_format: 目标格式

        Returns:
            标准化后的时间字符串
        """
        if not time_str:
            return ""

        # 清理时间字符串
        time_str = self.clean_text(time_str, remove_html=True, normalize_whitespace=True)

        # 尝试匹配各种时间格式
        for pattern, replacement in self.TIME_PATTERNS:
            match = re.search(pattern, time_str)
            if match:
                try:
                    # 提取年月日
                    year, month, day = match.groups()
                    # 格式化
                    formatted_date = f"{year}-{month.zfill(2)}-{day.zfill(2)}"

                    # 验证日期有效性
                    datetime.strptime(formatted_date, "%Y-%m-%d")
                    return formatted_date
                except ValueError:
                    if self.logger:
                        self.logger.warning(f"无效的日期格式: {time_str}")
                    continue

        # 如果无法解析，返回原始字符串
        if self.logger:
            self.logger.warning(f"无法解析时间格式: {time_str}")
        return time_str.strip()

    def extract_text_length(self, text: str, max_length: int = 100) -> str:
        """
        提取指定长度的文本

        Args:
            text: 原始文本
            max_length: 最大长度

        Returns:
            截取后的文本
        """
        if not text:
            return ""

        if len(text) <= max_length:
            return text

        # 在合适的位置截断
        truncated = text[:max_length]

        # 尝试在句号、问号、感叹号处截断
        for punct in ['。', '！', '？', '.', '!', '?']:
            pos = truncated.rfind(punct)
            if pos > max_length * 0.7:  # 在70%位置之后找到标点
                return truncated[:pos + 1]

        # 尝试在逗号处截断
        pos = truncated.rfind('，')
        if pos > max_length * 0.7:
            return truncated[:pos + 1]

        # 在空格处截断
        pos = truncated.rfind(' ')
        if pos > max_length * 0.7:
            return truncated[:pos]

        # 直接截断并添加省略号
        return truncated + "..."

    def validate_text(self, text: str, field_name: str,
                     max_length: Optional[int] = None) -> Dict[str, Any]:
        """
        验证文本内容

        Args:
            text: 要验证的文本
            field_name: 字段名称
            max_length: 最大长度限制

        Returns:
            验证结果字典
        """
        result = {
            'valid': True,
            'errors': [],
            'warnings': []
        }

        if not text:
            result['valid'] = False
            result['errors'].append(f"{field_name} 不能为空")
            return result

        # 检查长度
        if max_length and len(text) > max_length:
            result['warnings'].append(f"{field_name} 长度超过限制 ({len(text)}/{max_length})")

        # 检查是否包含特殊字符
        if re.search(r'[<>"\']', text):
            result['warnings'].append(f"{field_name} 包含特殊字符")

        # 检查是否全是空白字符
        if text.strip() == "":
            result['valid'] = False
            result['errors'].append(f"{field_name} 不能只包含空白字符")

        return result

    def normalize_chinese_text(self, text: str) -> str:
        """
        标准化中文文本

        Args:
            text: 原始文本

        Returns:
            标准化后的文本
        """
        if not text:
            return ""

        # 全角转半角
        text = self._fullwidth_to_halfwidth(text)

        # 标准化标点符号
        text = self._normalize_punctuation(text)

        return text

    def _fullwidth_to_halfwidth(self, text: str) -> str:
        """全角转半角"""
        result = ""
        for char in text:
            code = ord(char)
            if code == 0x3000:  # 全角空格
                result += ' '
            elif 0xFF01 <= code <= 0xFF5E:  # 全角字符
                result += chr(code - 0xFEE0)
            else:
                result += char
        return result

    def _normalize_punctuation(self, text: str) -> str:
        """标准化标点符号"""
        # 中文标点符号映射
        punctuation_map = {
            '，': ',',
            '。': '.',
            '！': '!',
            '？': '?',
            '；': ';',
            '：': ':',
            '"': '"',
            '"': '"',
            ''': "'",
            ''': "'",
            '（': '(',
            '）': ')',
            '【': '[',
            '】': ']',
            '《': '<',
            '》': '>',
        }

        for old, new in punctuation_map.items():
            text = text.replace(old, new)

        return text


# 创建全局文本处理器实例
text_processor = TextProcessor()
